import 'package:logger/logger.dart' as pkg;
import 'package:mobile_app.core/logger/log_level.dart';
import 'package:mobile_app.core/logger/log_printer.dart';

class Logger {
  static final _instance = Logger._internal();

  static LogLevel _logLevel = LogLevel.error;

  static late pkg.Logger _pkgLogger;

  static LogLevel get logLevel => _logLevel;

  static set logLevel(LogLevel logLevel) {
    if (_logLevel == logLevel) {
      return;
    }

    _logLevel = logLevel;

    _pkgLogger = _createPkgLogger(
      logLevel: _logLevel,
    );
  }

  Logger._internal() {
    _pkgLogger = _createPkgLogger(
      logLevel: _logLevel,
    );
  }

  factory Logger() {
    return _instance;
  }

  void v(String message) {
    _pkgLogger.v(message);
  }

  void i(String message) {
    _pkgLogger.i(message);
  }

  void w(String? message, [dynamic error, StackTrace? stackTrace]) {
    _pkgLogger.w(message, error, stackTrace);
  }

  void e(String? message, [dynamic error, StackTrace? stackTrace]) {
    _pkgLogger.e(message, error, stackTrace);
  }

  void close() {
    _pkgLogger.close();
  }
}

pkg.Level _createPkgLogLevel({
  required LogLevel logLevel,
}) {
  return switch (logLevel) {
    LogLevel.verbose => pkg.Level.verbose,
    LogLevel.debug => pkg.Level.debug,
    LogLevel.info => pkg.Level.info,
    LogLevel.warning => pkg.Level.warning,
    LogLevel.error => pkg.Level.error,
    LogLevel.wtf => pkg.Level.wtf,
    LogLevel.nothing => pkg.Level.nothing,
  };
}

pkg.Logger _createPkgLogger({
  required LogLevel logLevel,
}) {
  final pkgLogLevel = _createPkgLogLevel(
    logLevel: logLevel,
  );

  return pkg.Logger(
    printer: LogPrinter(
      methodCount: 0,
      errorMethodCount: 10,
      colors: true,
      stackTraceBeginIndex: 0,
    ),
    level: pkgLogLevel,
    output: pkg.ConsoleOutput(),
    filter: pkg.DevelopmentFilter(),
  );
}
